package com.example.authserver.model;

import com.example.authserver.util.JsonUtils;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.Getter;
import lombok.Setter;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Table;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.util.CollectionUtils;

import java.util.Optional;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author cjw
 * @date 2020/10/15  15:28
 */
@Getter
@Setter
@Table("client")
public class Client {
    @Id
    private String id;
    private String clientId;
    private String clientSecret;
    private String methods;
    private String grantTypes;
    private String redirectUri;
    private String scopes;

    public RegisteredClient toRegisteredClient() {

        RegisteredClient.Builder builder = RegisteredClient.withId(String.valueOf(id))
                .clientId(clientId)
                .clientSecret(clientSecret)
                .redirectUri(redirectUri);

        //请求方法
        builder.clientAuthenticationMethods(a ->
                new CosBiFunction<ClientAuthenticationMethod>()
                        .apply(this.methods, ClientAuthenticationMethod::new)
                        .ifPresent(a::addAll)
        );
        //作用域
        builder.scopes(a ->
                new CosBiFunction<String>()
                        .apply(this.scopes, b -> b)
                        .ifPresent(a::addAll)
        );
        //验证类型
        builder.authorizationGrantTypes(a ->
                new CosBiFunction<AuthorizationGrantType>()
                        .apply(this.grantTypes, AuthorizationGrantType::new)
                        .ifPresent(a::addAll)
        );
        return builder.build();
    }


    private static class CosBiFunction<T> implements BiFunction<String, Function<String, T>, Optional<Set<T>>> {
        @Override
        public Optional<Set<T>> apply(String a, Function<String, T> b) {
            Set<String> object = JsonUtils.jsonToObject(a, new TypeReference<Set<String>>() {
            });
            if (CollectionUtils.isEmpty(object)) {
                return Optional.empty();
            }
            return Optional.of(object.stream().map(b).collect(Collectors.toSet()));
        }
    }


}
